<!--
* @author wn
* @date 2022/08/22 15:11:42
* @description: 将 收货地址 添加 修改 地址 单独提取出来
*  使用  xtx-dialog 组件
!-->
<template>
	<xtx-dialog
		v-model="dialogVisible"
		:title="`${form.id ? '修改' : '添加'}收货地址`"
	>
		<!-- 默认插槽 -->
		<Form
			class="xtx-form"
			:validation-schema="mySchema"
			v-slot="{ errors }"
			ref="target"
		>
			<div class="xtx-form-item">
				<div class="label">收<i />货<i />人：</div>
				<Field
					name="receiver"
					v-model="form.receiver"
					type="text"
					placeholder="请输入收货人"
				/>
				<div class="error" v-if="errors.receiver">
					<i class="iconfont icon-warning" />
					{{ errors.receiver }}
				</div>
			</div>
			<div class="xtx-form-item">
				<div class="label">手<i />机<i />号：</div>
				<Field
					name="mobile"
					v-model="form.contact"
					type="number"
					placeholder="请输入手机号"
				/>
				<div class="error" v-if="errors.mobile">
					<i class="iconfont icon-warning" />
					{{ errors.mobile }}
				</div>
			</div>
			<div class="xtx-form-item">
				<div class="label">地<i class="two" />区：</div>
				<Field
					as="xtx-city"
					:fullLocation="form.fullLocation"
					@change="changeCity"
					name="fullLocation"
					type="text"
					placeholder="请选择所在地区"
				/>
				<div class="error" v-if="errors.fullLocation">
					<i class="iconfont icon-warning" />
					{{ errors.fullLocation }}
				</div>
			</div>
			<div class="xtx-form-item">
				<div class="label">详细地址：</div>
				<Field
					name="address"
					v-model="form.address"
					type="text"
					placeholder="请输入详细地址"
				/>
				<div class="error" v-if="errors.address">
					<i class="iconfont icon-warning" />
					{{ errors.address }}
				</div>
			</div>
			<div class="xtx-form-item">
				<div class="label">邮政编码：</div>
				<Field
					name="postalCode"
					v-model="form.postalCode"
					type="number"
					placeholder="请输入邮政编码"
				/>
				<div class="error" v-if="errors.postalCode">
					<i class="iconfont icon-warning" />
					{{ errors.postalCode }}
				</div>
			</div>
			<div class="xtx-form-item">
				<div class="label">地址标签：</div>
				<Field
					name="addressTags"
					v-model="form.addressTags"
					type="text"
					placeholder="请输入地址标签"
				/>
				<div class="error" v-if="errors.addressTags">
					<i class="iconfont icon-warning" />
					{{ errors.addressTags }}
				</div>
			</div>
		</Form>
		<!-- 具名插槽 -->
		<template #footer>
			<xtx-button
				@click="dialogVisible = false"
				type="gray"
				style="margin-right: 20px"
			>
				取消
			</xtx-button>
			<xtx-button @click="confirm" type="primary">确认</xtx-button>
		</template>
	</xtx-dialog>
</template>
<script>
import { Form, Field } from 'vee-validate'
import schema from '@/utils/vee-validate-schema'
import { ref, reactive, inject, nextTick } from 'vue'
import Message from '@/components/library/message'
import { addAddress, editAddress } from '@/network/order'
export default {
	name: 'AddressEdit',
	components: { Form, Field },
	setup() {
		// v-model 控制对话框的展示
		const dialogVisible = ref(false)
		// 组件实例定义 函数  父组件  ref="target" 获取实例  就可以直接调用
		// 但是此函数 必须 返回出去才可以
		const openDialog = showAddress => {
			dialogVisible.value = true
			/**
			 *  情况1：修改 - showAddress value传递过来  展示
			 *
			 *  情况2：添加 - 空表单
			 *  v-if v-show 数据变化 等 都属于要更新 DOM
			 *  nextTick 等 DOM 更新完毕 在执行 回调(在此之前属于虚拟DOM)
			 *  清空表单--点击时并没有获取 target DOM
			 */
			if (showAddress) {
				//  form 合并  showAddress
				Object.assign(form, showAddress)
			} else {
				nextTick(() => target.value.resetForm())
				for (const key in form) {
					form[key] = ''
				}
				// isDefault 的值不是字符串类型，是否为默认地址，0为是，1为否
				form.isDefault = 1
			}
		}
		const mySchema = {
			receiver: schema.receiver,
			mobile: schema.mobile,
			fullLocation: schema.fullLocation,
			address: schema.address,
			postalCode: schema.postalCode,
			addressTags: schema.addressTags,
		}
		// v-model changeCity 赋值
		const form = reactive({
			receiver: '', // 收货人姓名
			contact: '', // 联系方式
			address: '', // 详细地址
			postalCode: '', // 邮政编码
			addressTags: '', // 地址标签,以英文逗号分割
			provinceCode: '', // 所在省份编码
			cityCode: '', // 所在城市编码
			countyCode: '', // 所在区/县编码
			isDefault: 1, // 是否为默认，0为是，1为否
			// 考虑到这个表单对象还要实现修改，所以新增两个修改时所需的字段
			id: '', // 需要修改的地址id
			fullLocation: '', // 完整地址，用于城市组件展示的
		})
		/**
		 * 此处  schema 的数据绑定  虽然 :fullLocation="form.fullLocation"
		 * 但是  接收的值 是 @change 值 v  不是 v?.fullLocation
		 * 所以  Proxy{} 为true   所以 XtxCity close不能传 {}
		 * 修改地址时  一上来  组件就有数据  input通过 v-model 获取
		 * 自动触发 schema 接收值
		 * 自定义组件不支持 v-model 所以初始化时自动触发 @change 触发
		 * 自动触发 schema 接收值
		 * 但是此处仅仅需要发送值  不需要更改form
		 */
		const changeCity = v => {
			if (typeof v === 'string') return
			form.provinceCode = v?.provinceCode
			form.cityCode = v?.cityCode
			form.countyCode = v?.countyCode
			form.fullLocation = v?.fullLocation
		}
		/**
		 * 1 添加 或 新增 按钮
		 * 2 提交 表单数据  表单验证
		 * 3 更新 地址列表  这里采用 API更新
		 * 4 关闭 对话框组件
		 */
		const getAddressList = inject('getAddressList')
		const target = ref(null)
		const confirm = async () => {
			const valid = await target.value.validate()
			if (!valid) return Message({ type: 'warn', message: '表单校验失败' })
			// 修改API  有 id
			// 添加API  无 id 返回 id
			form.id ? await editAddress(form) : await addAddress(form)
			Message({
				type: 'success',
				message: `${form.id ? '修改' : '添加'}收货地址成功`,
			})
			// form.id = result.id
			// 获取最新的地址列表  checkout 依赖注入
			getAddressList()
			// 修改 地址 需要 id
			// 关闭窗口
			dialogVisible.value = false
		}
		return {
			dialogVisible,
			openDialog,
			mySchema,
			form,
			changeCity,
			target,
			confirm,
		}
	},
}
</script>
<style scoped lang="less">
.xtx-dialog {
	:deep(.wrapper) {
		width: 780px;
		.body {
			max-height: 600px;
			padding: 20px 0;
			font-size: 14px;
		}
	}
}
.xtx-form {
	margin: 0;
	padding-left: 120px;
	&-item {
		div:nth-child(1) {
			width: 80px;
			text-align: right;
			margin-right: 5px;
		}
	}
	// i {
	// 	display: inline-block;
	// 	width: 0.5em;
	// }
	// .two {
	// 	width: 2em;
	// }
	input {
		height: 50px;
		width: 320px;
		border: 1px solid #e4e4e4;
		padding-left: 10px;
		&::placeholder {
			color: #ccc;
		}
	}
}
.xtx-city {
	width: 320px;
	:deep(.select) {
		height: 50px;
		line-height: 48px;
		display: flex;
		padding: 0 10px;
		justify-content: space-between;
		.placeholder {
			color: #ccc;
		}
		i {
			color: #ccc;
			font-size: 18px;
		}
		.value {
			font-size: 14px;
		}
	}
	:deep(.option) {
		top: 49px;
	}
}
</style>
